#include "echo.h"

#define BUF_LEN 4096

int main() 
{
   int sock, listener;
   char buf[BUF_LEN];
   int bytes_read;
   #ifdef TCP
   listener = socket(AF_INET, SOCK_STREAM, 0);
   #else
   listener = socket(AF_INET, SOCK_DGRAM, 0);
   #endif

   if(listener == -1)
   {
      perror("Create listener: ");
      exit(errno);
   }

   addr.sin_family = AF_INET;
   addr.sin_port = htons(ECHO_PORT);
   addr.sin_addr.s_addr = htonl(INADDR_ANY);

   if(bind(listener, (struct sockaddr *)&addr, sizeof(addr)) == -1)
   {
      perror("Couldn't bind to address: ");
      exit(errno);
   }
   
   #ifdef TCP
   listen(listener, 10);
   #endif

   while(1)
   {
      int client_address_len = sizeof(struct sockaddr_in);
      struct sockaddr_in client_address;
      bzero(&buf, sizeof(buf));
      #ifdef TCP
      sock = accept(listener, (struct sockaddr *) &client_address, &client_address_len);
      if(sock < 0)
      {
         perror("Accept connection: ");
         exit(errno);
      }
      bytes_read = read_all(sock, buf, BUF_LEN);
      if(bytes_read < 0) 
         perror("Transfer problems");
      else 
      {
         char *address = inet_ntoa(client_address.sin_addr);
         printf("Received from %s:%d: %s\n", address, ntohs(addr.sin_port), buf);
         write_all(sock, buf, bytes_read);
      }
      close(sock);
      #else //UDP
      int len = recvfrom(listener, buf, BUF_LEN, 0, (struct sockaddr*)&client_address, &client_address_len);
      if (len > 0) {
         buf[len] = 0;
         printf("Received from %s:%d: %s\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), buf);
         sendto(listener, buf, len, 0, (struct sockaddr*)&client_address, client_address_len);
      } else {
         perror("Failed to receive a UDP datagram from a remote host");
      }
      #endif
   }
   close(listener);
   return 0;
}
